//
//  TYAlertView.m
//  Pods
//
//  Created by Lucca on 2019/2/20.
//
//

#import "TYUIKit.h"

#import "TYAlertView.h"
#import "TYAlertShadowView.h"
#import "TYAlertViewWindow.h"
#import "TYAlertViewTextField.h"
#import "TYAlertViewController.h"
#import "TYAlertViewWindowObserver.h"
#import "TYTheme.h"

CGFloat const TYAlertViewPaddingWidth = 20.0;
CGFloat const LTYlertViewPaddingHeight = 8.0;

NSString *const TYAlertRemoveAllAlertNotification = @"TYAlertRemoveAllAlertNotification";

@interface TYAlertAction()

@property (nonatomic, assign) NSInteger index;
@property (nonatomic, assign) BOOL noneFont;

@end

@implementation TYAlertAction

- (instancetype)init {
    if (self = [super init]) {
        self.title = @"完成";
        self.noneFont = YES;
        self.titleColor = TYTheme.theme.B4.N1;
        UIColor* color = TYTheme.theme.status_font_color;
        UIStatusBarStyle style = TYTheme.theme.preferredStatusBarStyle;
        self.titleFont = [UIFont systemFontOfSize:TY_ScreenAdaptionLength(16)];
        self.textAligment = NSTextAlignmentCenter;
        self.backgroundColorHighlighted = TYTheme.theme.B4_2;
        self.isCancel = NO;
    }
    return self;
}

- (void)setTitleColor:(UIColor *)titleColor{
    _titleColor = titleColor;
    _titleColorHighlighted = titleColor;
    _titleColorDisabled = titleColor;
}

- (void)setIsCancel:(BOOL)isCancel {
    if (self.noneFont) {
        self.titleFont = isCancel ? [UIFont systemFontOfSize:TY_ScreenAdaptionLength(16) weight:UIFontWeightSemibold] : [UIFont systemFontOfSize:TY_ScreenAdaptionLength(16)];
    }
    _isCancel = isCancel;
}

+ (TYAlertAction *)actionWithTitle:(NSString *)title alertAciton:(AlertAtcion)action {
    return [self actionWithTitle:title color:nil font:nil alertAciton:action];
}


+ (TYAlertAction *)actionWithTitle:(NSString *)title color:(UIColor *)color font:(UIFont *)font alertAciton:(AlertAtcion)action {
    TYAlertAction *alertAction = [[TYAlertAction alloc] init];
    alertAction.title = title;
    alertAction.noneFont = YES;
    if (color) {
        alertAction.titleColor = color;
    }
    if (font) {
        alertAction.noneFont = NO;
        alertAction.titleFont = font;
    }
    alertAction.alertAction = action;
    return alertAction;
}


+ (TYAlertAction *)actionWithTitle:(NSString *)title
                        titleColor:(UIColor *)titleColor
             titleColorHighlighted:(UIColor *)titleColorHighlighted
                   backgroundColor:(UIColor *)backgroundColor
        backgroundColorHighlighted:(UIColor *)backgroundColorHighlighted
                              font:(UIFont *)font
                       alertAciton:(AlertAtcion)action
                      textAligment:(NSTextAlignment)textAligment
                          isCancel:(BOOL)isCancel {
    
    TYAlertAction *alertAction = [[TYAlertAction alloc] init];
    alertAction.title = title;
    alertAction.alertAction = action;
    alertAction.textAligment = textAligment;
    alertAction.isCancel = isCancel;
    
    if (titleColor) {
        alertAction.titleColor = titleColor;
    }
    
    alertAction.noneFont = YES;
    if (font) {
        alertAction.noneFont = NO;
        alertAction.titleFont = font;
    } else if (isCancel) {
        alertAction.titleFont = [UIFont systemFontOfSize:TY_ScreenAdaptionLength(16) weight:UIFontWeightSemibold];
    }
    
    if (backgroundColor) {
        alertAction.backgroundColor = backgroundColor;
    }
    
    if (backgroundColorHighlighted) {
        alertAction.backgroundColorHighlighted = backgroundColorHighlighted;
    }
    
    if (titleColorHighlighted) {
        alertAction.titleColorHighlighted = titleColorHighlighted;
    }
    
    return alertAction;
}

@end

typedef enum : NSUInteger {
    TYAlertViewTypeDefault,
    TYAlertViewTypeTextField,
    TYAlertViewTypeProgressView
} TYAlertViewType;


@interface TYAlertView() <UIGestureRecognizerDelegate, UITextFieldDelegate>

@property (readwrite) BOOL             showing;
@property (readwrite) TYAlertViewStyle style;

@property (readwrite) NSString         *title;
@property (readwrite) NSString         *message;
@property (readwrite) UIView           *innerView;
@property (readwrite) NSArray          *buttonTitles;
@property (readwrite) NSString         *cancelButtonTitle;
@property (readwrite) NSArray<UITextField *> *textFieldsArray;

@property (nonatomic, weak) UIView *showInView;
@property (nonatomic, strong) UIView   *view;
@property (nonatomic, assign) BOOL     initialized;
@property (nonatomic, assign) BOOL     isShowInView;

@property (nonatomic, assign) CGFloat  maxHeight;
@property (nonatomic, assign) CGFloat  headerHeight;
@property (assign, nonatomic) CGPoint  scrollViewCenterShowed;
@property (assign, nonatomic) CGPoint  scrollViewCenterHidden;

@property (assign, nonatomic) CGPoint  cancelButtonCenterShowed;
@property (assign, nonatomic) CGPoint  cancelButtonCenterHidden;

@property (assign, nonatomic) CGPoint  cancelSepViewCenterHidden;
@property (assign, nonatomic) CGPoint  cancelSepViewCenterShowed;

@property (nonatomic, assign) TYAlertViewType  type;
@property (assign, nonatomic, getter=isExists) BOOL exists;

@property (nonatomic, assign) CGFloat          keyboardHeight;
@property (nonatomic, assign) CGFloat          cancelButtonOffsetY;

@property (strong, nonatomic) TYButton          *titleBtn;
@property (strong, nonatomic) UILabel          *messageLabel;
@property (strong, nonatomic) UIView           *innerContainerView;

@property (strong, nonatomic) UIProgressView   *progressView;
@property (strong, nonatomic) UILabel          *progressLabel;

@property (nonatomic, strong) UIButton         *cancelButton;

@property (strong, nonatomic) TYAlertShadowView     *shadowCancelView;
@property (strong, nonatomic) UIVisualEffectView    *blurCancelView;

@property (nonatomic, strong) TYAlertShadowView     *shadowView;
@property (strong, nonatomic) UIVisualEffectView    *backgroundView;

@property (nonatomic, strong) UIView                *cancelSeperateView;


@property (nonatomic, strong) TYAlertViewController *viewController;

@property (nonatomic, strong) NSMutableArray     *actions;
@property (nonatomic, strong) UIView             *contentView;

@property (nonatomic, strong) UIScrollView       *titleScrollView;
@property (nonatomic, strong) UIScrollView       *contentScrollView;
@property (nonatomic, strong) UIScrollView       *buttonScrollView;

@property (nonatomic, strong) UIView             *blurContentView;
@property (nonatomic, strong) UIVisualEffectView *blurView;


@property (nonatomic, assign) NSUInteger         numberOfTextFields;
@property (nonatomic, strong) TYAlertAction      *cancelAction;
@property (nonatomic, strong) TYAlertViewWindow  *alertWindow;


@property (nonatomic, copy) TYAlertViewActionHandler          actionHandler;
@property (nonatomic, copy) TYAlertViewTextFieldsSetupHandler textFieldsSetupHandler;

/// 用于盛放按钮的容器
@property (nonatomic, strong) NSMutableArray     *alertBtns;

@property (nonatomic, strong) NSTimer* countDownTimer;

@end


@implementation TYAlertView


- (nonnull instancetype)initSimpleAlertWithTitle:(nullable NSString *)title
                                         message:(nullable NSString *)message
                                           style:(TYAlertViewStyle)style {
    if (self = [super init]) {
        self.title = title;
        self.message = message;
        self.style = style;
        self.type = TYAlertViewTypeDefault;
        
        [self initDefaultPropertys];
    }
    return self;
}
- (nonnull instancetype)initWithTitle:(nullable NSString *)title
                              message:(nullable NSString *)message
                                style:(TYAlertViewStyle)style
                         buttonTitles:(nullable NSArray<NSString *> *)buttonTitles
                    cancelButtonTitle:(nullable NSString *)cancelButtonTitle
                        actionHandler:(TYAlertViewActionHandler)actionHandler {
    if (self = [super init]) {
        self.title = title;
        self.message = message;
        self.style = style;
        self.type = TYAlertViewTypeDefault;
        self.buttonTitles = buttonTitles;
        self.actionHandler = actionHandler;
        self.cancelButtonTitle = cancelButtonTitle;
        
        [self initDefaultPropertys];
    }
    return self;
}



- (nonnull instancetype)initWithViewAndTitle:(nullable NSString *)title
                                     message:(nullable NSString *)message
                                        view:(nullable UIView *)view
                                       style:(TYAlertViewStyle)style
                                buttonTitles:(nullable NSArray<NSString *> *)buttonTitles
                           cancelButtonTitle:(nullable NSString *)cancelButtonTitle
                               actionHandler:(TYAlertViewActionHandler)actionHandler {
    if (self = [super init]) {
        self.title = title;
        self.message = message;
        self.style = style;
        self.type = TYAlertViewTypeDefault;
        self.innerView = view;
        self.buttonTitles = buttonTitles;
        self.actionHandler = actionHandler;
        self.cancelButtonTitle = cancelButtonTitle;
        
        [self initDefaultPropertys];
    }
    return self;
}


- (nonnull instancetype)initWithTextFieldAndTitle:(nullable NSString *)title
                                          message:(nullable NSString *)message
                                numberOfTextField:(NSInteger)numberOfTextFields
                           textFieldsSetupHandler:(TYAlertViewTextFieldsSetupHandler)textFieldsSetupHandler
                                     buttonTitles:(nullable NSArray<NSString *> *)buttonTitles
                                cancelButtonTitle:(nullable NSString *)cancelButtonTitle
                                    actionHandler:(TYAlertViewActionHandler)actionHandler {
    if (self = [super init]) {
        self.title = title;
        self.message = message;
        self.numberOfTextFields = numberOfTextFields;
        self.style = TYAlertViewStyleAlert;
        self.type = TYAlertViewTypeTextField;
        self.textFieldsSetupHandler = textFieldsSetupHandler;
        self.buttonTitles = buttonTitles;
        self.actionHandler = actionHandler;
        self.cancelButtonTitle = cancelButtonTitle;
        
        [self initDefaultPropertys];
    }
    return self;
}

- (nonnull instancetype)initWithProgressViewAndTitle:(nullable NSString *)title
                                             message:(nullable NSString *)message
                                            progress:(float)progress
                                   progressLabelText:(nullable NSString *)progressLabelText
                                               style:(TYAlertViewStyle)style
                                        buttonTitles:(nullable NSArray<NSString *> *)buttonTitles
                                   cancelButtonTitle:(nullable NSString *)cancelButtonTitle
                                       actionHandler:(TYAlertViewActionHandler)actionHandler {
    if (self = [super init]) {
        self.title = title;
        self.message = message;
        self.style = TYAlertViewStyleAlert;
        self.type = TYAlertViewTypeTextField;
        self.buttonTitles = buttonTitles;
        self.actionHandler = actionHandler;
        self.cancelButtonTitle = cancelButtonTitle;
        
        [self initDefaultPropertys];
    }
    return self;
}


+ (nonnull instancetype)showSimpleAlertViewWithTitle:(nullable NSString *)title
                                             message:(nullable NSString *)message
                                               style:(TYAlertViewStyle)style
                                         cancelTitle:(nullable NSString *)cancelTitle {
    TYAlertView *alertView = [[TYAlertView alloc] initWithTitle:title message:message style:style buttonTitles:nil cancelButtonTitle:cancelTitle actionHandler:nil];
    [alertView showAnimated];
    return alertView;
}


+ (nonnull instancetype)showTextFieldAlertViewWithTitle:(nullable NSString *)title
                                                message:(nullable NSString *)message
                                      numberOfTextField:(NSInteger)numberOfTextFields
                                 textFieldsSetupHandler:(TYAlertViewTextFieldsSetupHandler)textFieldsSetupHandler
                                           buttonTitles:(nullable NSArray<NSString *> *)buttonTitles
                                      cancelButtonTitle:(nullable NSString *)cancelButtonTitle
                                          actionHandler:(TYAlertViewActionHandler)actionHandler {
    TYAlertView *alertView = [[TYAlertView alloc] initWithTextFieldAndTitle:title message:message numberOfTextField:numberOfTextFields textFieldsSetupHandler:textFieldsSetupHandler buttonTitles:buttonTitles cancelButtonTitle:cancelButtonTitle actionHandler:actionHandler];
    [alertView showAnimated];
    return alertView;
}

+ (nonnull instancetype)showAlertViewWithTitle:(nullable NSString *)title
                                       message:(nullable NSString *)message
                                          view:(nullable UIView *)view
                                         style:(TYAlertViewStyle)style
                                  buttonTitles:(nullable NSArray<NSString *> *)buttonTitles
                             cancelButtonTitle:(nullable NSString *)cancelButtonTitle
                                 actionHandler:(TYAlertViewActionHandler)actionHandler {
    TYAlertView *alertView = [[TYAlertView alloc] initWithTitle:title message:message style:style buttonTitles:buttonTitles cancelButtonTitle:cancelButtonTitle actionHandler:actionHandler];
    [alertView showAnimated];
    return alertView;
}

+ (nonnull instancetype)showAlertViewWithTitle:(nullable NSString *)title
                                       message:(nullable NSString *)message
                                   contentView:(nullable UIView *)contentView
                                         style:(TYAlertViewStyle)style
                                  buttonTitles:(nullable NSArray<NSString *> *)buttonTitles
                             cancelButtonTitle:(nullable NSString *)cancelButtonTitle
                                 actionHandler:(TYAlertViewActionHandler)actionHandler {
    TYAlertView *alertView = [[TYAlertView alloc] initWithViewAndTitle:title message:message view:contentView style:style buttonTitles:buttonTitles cancelButtonTitle:cancelButtonTitle actionHandler:actionHandler];
    [alertView showAnimated];
    return alertView;
}


+ (nonnull instancetype)showProgressAlertViewWithTitle:(nullable NSString *)title
                                               message:(nullable NSString *)message
                                              progress:(float)progress
                                     progressLabelText:(nullable NSString *)progressLabelText
                                                 style:(TYAlertViewStyle)style
                                          buttonTitles:(nullable NSArray<NSString *> *)buttonTitles
                                     cancelButtonTitle:(nullable NSString *)cancelButtonTitle
                                         actionHandler:(TYAlertViewActionHandler)actionHandler {
    TYAlertView *alertView = [[TYAlertView alloc] initWithProgressViewAndTitle:title message:message progress:progress progressLabelText:progressLabelText style:style buttonTitles:buttonTitles cancelButtonTitle:cancelButtonTitle actionHandler:actionHandler];
    [alertView showAnimated];
    return alertView;
}

+ (nonnull instancetype)showAlertViewWithTitle:(nullable NSString *)title
                                       message:(nullable NSString *)message
                                   contentView:(nullable UIView *)contentView
                                         style:(TYAlertViewStyle)style
                                  buttonTitles:(nullable NSArray<NSString *> *)buttonTitles
                             cancelButtonTitle:(nullable NSString *)cancelButtonTitle
                              cancelButtonBold:(BOOL)isBold
                                 actionHandler:(TYAlertViewActionHandler)actionHandler {
    TYAlertView *alertView = [[TYAlertView alloc] initWithViewAndTitle:title message:message view:contentView style:style buttonTitles:buttonTitles cancelButtonTitle:cancelButtonTitle actionHandler:actionHandler];
    alertView.cancleFont = [UIFont systemFontOfSize:TY_ScreenAdaptionLength(16)];
    [alertView showAnimated];
    return alertView;
}



#pragma mark - init default property
- (void)initDefaultPropertys {
    _dismissOnAction = YES;
    _cancelOnTouch = self.style == TYAlertViewStyleActionSheet;
    _coverColor = TYTheme.theme.B1.N8;
    _coverBlurEffect = nil;
    _coverAlpha = 1.0;
    _backgroundColor = TYTheme.theme.B4;
    _backgroundBlurEffect = nil;
    _width = 0;
    _shouldDismissAnimated = YES;
    _buttonHeight = TY_ScreenAdaptionLength(50);
    _cancelButtonOffsetY = 10.0;
    if (@available(iOS 11.0, *)) {
        CGFloat bottom = [UIApplication sharedApplication].keyWindow.safeAreaInsets.bottom;
        self.cancelButtonOffsetY = bottom > 0 ? bottom : TY_ScreenAdaptionLength(8.0);
    }
    if (self.style == TYAlertViewStyleAlert) {
        _layerCornerRadius = TYTheme.theme.C2;
    }
    _layerBorderColor = nil;
    _layerBorderWidth = 0.0;
    _layerShadowColor = nil;
    _layerShadowRadius = 0.0;
    _layerShadowOffset = CGPointZero;
    
    _titleTextColor = TYTheme.theme.B4.N1;
    _titleTextAlignment = NSTextAlignmentCenter;
    _titleFont = [UIFont systemFontOfSize:TY_ScreenAdaptionLength(16) weight:UIFontWeightSemibold];;
    _tintColor = TYTheme.theme.M1;
    
    _messageTextColor = TYTheme.theme.B4.N2;
    _messageTextAlignment = NSTextAlignmentCenter;
    _messageFont = [UIFont systemFontOfSize:TY_ScreenAdaptionLength(14)];
    _messageLineSpacing = TY_ScreenAdaptionLength(3.f);
    _seperateLineBetweenTitleAndMessage = NO;
    
    _progressViewTrackTintColor = TYTheme.theme.M1;
    _progressViewProgressImage = nil;
    _progressViewTrackImage = nil;
    
    _progressLabelTextColor = TYTheme.theme.B4.N2;
    _progressLabelTextAlignment = NSTextAlignmentCenter;
    _progressLabelFont = [UIFont systemFontOfSize:TY_ScreenAdaptionLength(14.0)];
    _progressLabelNumberOfLines = 1;
    _progressLabelLineBreakMode = NSLineBreakByTruncatingTail;
    
    _textFieldsBackgroundColor = [UIColor clearColor];
    _textFieldsTextColor = TYTheme.theme.B4.N1;
    _textFieldsFont = [UIFont systemFontOfSize:TY_ScreenAdaptionLength(14.0)];
    _textFieldsTextAlignment = NSTextAlignmentLeft;
    _textFieldsClearsOnBeginEditing = NO;
    _textFieldsAdjustsFontSizeToFitWidth = NO;
    _textFieldsMinimumFontSize = TY_ScreenAdaptionLength(12.0);
    _textFieldsHeight = TY_ScreenAdaptionLength(44.0);
    
    _cancleFont = [UIFont systemFontOfSize:TY_ScreenAdaptionLength(16)];
    _otherFont = [UIFont systemFontOfSize:TY_ScreenAdaptionLength(16)];
    
    self.view = [UIView new];
    self.view.backgroundColor = UIColor.clearColor;
    self.view.userInteractionEnabled = YES;
    self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    
    self.backgroundView = [[UIVisualEffectView alloc] initWithEffect:self.coverBlurEffect];
    self.backgroundView.alpha = 0.0;
    self.backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.view addSubview:self.backgroundView];
    
    // -----
    
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cancelAction:)];
    tapGesture.delegate = self;
    [self.backgroundView addGestureRecognizer:tapGesture];
    
    // -----
    
    self.viewController = [[TYAlertViewController alloc] initWithAlertView:self view:self.view];
    
    self.alertWindow = [[TYAlertViewWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.alertWindow.hidden = YES;
    self.alertWindow.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.alertWindow.opaque = NO;
    self.alertWindow.backgroundColor = UIColor.clearColor;
    self.alertWindow.rootViewController = self.viewController;
    
    [self initTitleActions];
    
    // -----
    self.initialized = YES;
}

- (void)initTitleActions {
    
    self.actions = [@[] mutableCopy];
    NSInteger index = self.cancelButtonTitle ? 1 : 0;
    
    [self.buttonTitles enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        TYAlertAction *action = [TYAlertAction actionWithTitle:obj titleColor:nil titleColorHighlighted:nil backgroundColor:nil backgroundColorHighlighted:nil font:nil alertAciton:nil textAligment:NSTextAlignmentCenter isCancel:NO];
        action.index = idx + index;
        [self.actions addObject:action];
    }];
    
    if (self.cancelButtonTitle) {
        UIFont *cancelFont = [UIFont systemFontOfSize:TY_ScreenAdaptionLength(16) weight:UIFontWeightSemibold];
        TYAlertAction *cancelAction = [TYAlertAction actionWithTitle:self.cancelButtonTitle titleColor:TYTheme.theme.B4.N2 titleColorHighlighted:nil backgroundColor:nil backgroundColorHighlighted:nil font:cancelFont alertAciton:nil textAligment:NSTextAlignmentCenter isCancel:YES];
        cancelAction.index = 0;
        cancelAction.isCancel = YES;
        if (self.cancelButtonOffsetY != 0 && self.style == TYAlertViewStyleActionSheet) {
            self.cancelAction = cancelAction;
        } else {
            if (self.actions.count < 2) {
                [self.actions insertObject:cancelAction atIndex:0];
            } else {
                [self.actions addObject:cancelAction];
            }
        }
    }
}

#pragma mark - Keyboard notifications

- (void)keyboardVisibleChanged:(NSNotification *)notification {
    if (!self.isShowing || self.alertWindow.isHidden || !self.alertWindow.isKeyWindow) return;
    
    NSDictionary *notificationUserInfo = notification.userInfo;
    CGFloat keyboardHeight = (notificationUserInfo[UIKeyboardFrameEndUserInfoKey] ? CGRectGetHeight([notificationUserInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]) : 0.0);
    
    if (!keyboardHeight) return;
    
    NSTimeInterval animationDuration = [notificationUserInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    int animationCurve = [notificationUserInfo[UIKeyboardAnimationCurveUserInfoKey] intValue];
    
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:animationDuration];
    [UIView setAnimationCurve:animationCurve];
    
    if ([notification.name isEqualToString:UIKeyboardWillShowNotification]) {
        self.keyboardHeight = keyboardHeight;
    }
    else {
        self.keyboardHeight = 0.0;
    }
    [self layoutViewsWithSize:self.view.bounds.size];
    
    [UIView commitAnimations];
}

- (void)keyboardFrameChanged:(NSNotification *)notification {
    if (!self.isShowing ||
        self.alertWindow.isHidden ||
        !self.alertWindow.isKeyWindow ||
        [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue] != 0.0) {
        return;
    }
    
    self.keyboardHeight = CGRectGetHeight([notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]);
}

#pragma mark - Window notifications

- (void)windowVisibleChanged:(NSNotification *)notification {
    if (notification.object == self.alertWindow) {
        [self.viewController.view setNeedsLayout];
    }
}


#pragma mark - Observers

- (void)addObservers {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardVisibleChanged:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardVisibleChanged:) name:UIKeyboardWillHideNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardFrameChanged:) name:UIKeyboardWillChangeFrameNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowVisibleChanged:) name:UIWindowDidBecomeVisibleNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeSelfFromWindow) name:TYAlertRemoveAllAlertNotification object:nil];
    
}

- (void)removeObservers {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIWindowDidBecomeVisibleNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:TYAlertRemoveAllAlertNotification object:nil];
    
}



#pragma mark - Class load

+ (void)load {
    static dispatch_once_t token;
    dispatch_once(&token, ^{
        [[TYAlertViewWindowObserver sharedInstance] startObserving];
    });
}

#pragma mark - Dealloc

- (void)dealloc {
    [self removeObservers];
}

#pragma mark - Show

- (void)showAnimated:(BOOL)animated completionHandler:(TYAlertHandler)completionHandler {
    [self showAnimated:animated view:nil completionHandler:completionHandler];
}

- (void)showAnimated {
    [self showAnimated:YES completionHandler:nil];
}

- (void)show {
    [self showAnimated:YES completionHandler:nil];
}

- (void)showInView:(UIView *)view {
    [self showAnimated:YES view:view completionHandler:nil];
}

- (void)showAnimated:(BOOL)animated view:(UIView *)view completionHandler:(TYAlertHandler)completionHandler {
    if (!self.initialized || self.isShowing) return;
    self.showInView = view;
    self.alertWindow.windowLevel = UIWindowLevelStatusBar + 1;
    
    if (!view) {
        [self setupViewsWithSize:CGSizeZero];
        [self layoutViewsWithSize:CGSizeZero];
        
        self.view.userInteractionEnabled = NO;
//        UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
//        if (keyWindow != [TYAlertView appWindow]) {
//            keyWindow.hidden = YES;
//        }
        for (UIWindow *obj in [UIApplication sharedApplication].windows) {
            if ([obj isKindOfClass:[TYAlertViewWindow class]]) {
                obj.hidden = true;
            }
        }
        
        [self.alertWindow makeKeyAndVisible];
    } else {
        [self setupViewsWithSize:view.frame.size];
        [self layoutViewsWithSize:view.frame.size];
        
        self.isShowInView = YES;
        [view addSubview:self.view];
    }
    
    self.showing = YES;
    
    [self addObservers];
    
    if (self.willShowHandler) {
        self.willShowHandler(self);
    }
    
    if (animated) {
        [UIView animateWithDuration:0.5
                              delay:0.0
             usingSpringWithDamping:1.0
              initialSpringVelocity:0.5
                            options:0
                         animations:^{
            [self animationViews];
        } completion:^(BOOL finished) {
            
            if (self.type == TYAlertViewTypeTextField && self.textFieldsArray.count) {
                [self.textFieldsArray[0] becomeFirstResponder];
            }
            self.view.userInteractionEnabled = YES;
            
            if (completionHandler) {
                completionHandler();
            }
            
            if (self.didShowHandler) {
                self.didShowHandler(self);
            }
        }];
    }
    
}


- (void)animationViews {
    self.backgroundView.alpha = self.coverAlpha;
    
    if (self.style == TYAlertViewStyleAlert) {
        self.contentView.transform = CGAffineTransformIdentity;
        self.contentView.alpha = 1.0;
        
        self.shadowView.transform = CGAffineTransformIdentity;
        self.shadowView.alpha = 1.0;
        
        self.blurView.transform = CGAffineTransformIdentity;
        self.blurView.alpha = 1.0;
    }
    else {
        self.contentView.center = self.scrollViewCenterShowed;
        
        self.shadowView.center = self.scrollViewCenterShowed;
        
        self.blurView.center = self.scrollViewCenterShowed;
    }
    
    if (self.isCancelButtonSperateWithSelf && self.cancelButton) {
        self.cancelButton.center = self.cancelButtonCenterShowed;
        
        self.shadowCancelView.center = self.cancelButtonCenterShowed;
        
        self.blurCancelView.center = self.cancelButtonCenterShowed;
        
        self.cancelSeperateView.center = self.cancelSepViewCenterShowed;
    }
}

#pragma mark - dismiss

- (void)removeSelfFromWindow {
    if (self.keepOnWindowWhenRecieveRemoveNotification) {
        return;
    }
    [self dismissAnimated:NO completionHandler:nil];
}


- (void)dismissAnimated:(BOOL)animated completionHandler:(TYAlertHandler)completionHandler {
    if (!self.isShowing) return;
    
    self.view.userInteractionEnabled = NO;
    
    self.showing = NO;
    
    [self.view endEditing:YES];
    
    if (self.willDismissHandler) {
        self.willDismissHandler(self);
    }
    
    if (animated) {
        
        [UIView animateWithDuration:0.5
                              delay:0.0
             usingSpringWithDamping:1.0
              initialSpringVelocity:0.5
                            options:0
                         animations:^{
            [self dismissAnimationView];
        } completion:^(BOOL finished) {
            [self dismissComplete];
            
            if (completionHandler) {
                completionHandler();
            }
        }];
    }
    else {
        [self dismissAnimationView];
        [self dismissComplete];
        
        if (completionHandler) {
            completionHandler();
        }
    }
}

- (void)dismissAnimated {
    [self dismissAnimated:YES completionHandler:nil];
}

- (void)dismiss {
    [self dismissAnimated:NO completionHandler:nil];
}


- (void)dismissComplete {
    [self removeObservers];
    
    self.alertWindow.hidden = YES;
    
    if (self.didDismissHandler) {
        self.didDismissHandler(self);
    }
    // -----
    if (self.isShowInView) {
        [self.view removeFromSuperview];
    }
    
    self.view = nil;
    self.viewController = nil;
    self.alertWindow = nil;
}

- (void)dismissAnimationView {
    self.backgroundView.alpha = 0.0;
    
    if (self.style == TYAlertViewStyleAlert) {
        CGAffineTransform transform = CGAffineTransformMakeScale(0.9, 0.9);
        CGFloat alpha = 0.0;
        
        self.contentView.transform = transform;
        self.contentView.alpha = alpha;
        
        self.shadowView.transform = transform;
        self.shadowView.alpha = alpha;
        
        self.blurView.transform = transform;
        self.blurView.alpha = alpha;
    }
    else {
        self.contentView.center = self.scrollViewCenterHidden;
        
        self.cancelSeperateView.center = self.cancelSepViewCenterHidden;
        
        self.shadowView.center = self.scrollViewCenterHidden;
        
        self.blurView.center = self.scrollViewCenterHidden;
    }
    
    if ([self isCancelButtonSperateWithSelf] && self.cancelButton) {
        self.cancelButton.center = self.cancelButtonCenterHidden;
        
        self.shadowCancelView.center = self.cancelButtonCenterHidden;
        
        self.blurCancelView.center = self.cancelButtonCenterHidden;
    }
}

#pragma mark - layout views


- (void)setupViewsWithSize:(CGSize)size {
    if (CGSizeEqualToSize(size, CGSizeZero)) {
        size = self.viewController.view.bounds.size;
    }
    
    CGFloat width = self.width;
    
    if (!self.isExists) {
        self.exists = YES;
        
        [self addBackgroundView];
        [self addShadowView];
        [self addBlurView];
        [self addContentView];
        [self addTitleScrollView];
        [self addContentScrollView];
        [self addButtonScrollView];
        CGFloat contentOffsetY = 0.0;
        BOOL enableFirstButton = YES;
        
        if (self.title.length > 0) {
            self.titleBtn = [TYButton new];
            self.titleBtn.ty_imageTitleSpace = TY_ScreenAdaptionLength(5);
            if (self.subTitle.length > 0) {
                NSMutableParagraphStyle *stringStyle = [[NSMutableParagraphStyle alloc] init];
                stringStyle.lineSpacing = self.subTitleSpacing;
                stringStyle.alignment = self.titleTextAlignment;
                NSMutableAttributedString* titleAtt = [[NSMutableAttributedString alloc]initWithString:[NSString stringWithFormat:@"%@\n%@", self.title, self.subTitle] attributes:@{NSParagraphStyleAttributeName: stringStyle, NSForegroundColorAttributeName: self.titleTextColor, NSFontAttributeName: self.titleFont}];
                
//                NSMutableAttributedString* subAtt = [[NSMutableAttributedString alloc]initWithString:self.subTitle];
                [titleAtt addAttributes:@{NSForegroundColorAttributeName: self.subTitleTextColor, NSFontAttributeName: self.subTitleFont} range:NSMakeRange(self.title.length + 1, self.subTitle.length )];
                
//                [titleAtt appendAttributedString:subAtt];
                
                [self.titleBtn setAttributedTitle:titleAtt forState:UIControlStateNormal];
                
            }
            else {
                [self.titleBtn setTitle:self.title forState:UIControlStateNormal];
            }
            [self.titleBtn setImage:self.titleImage forState:UIControlStateNormal];
            [self.titleBtn setTitleColor:self.titleTextColor forState:UIControlStateNormal];
            self.titleBtn.titleLabel.textAlignment = self.titleTextAlignment;
            self.titleBtn.titleLabel.numberOfLines = 5;
            self.titleBtn.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
            self.titleBtn.backgroundColor = UIColor.clearColor;
            self.titleBtn.titleLabel.font = self.titleFont;
            
            CGSize titleLabelSize = [self.titleBtn sizeThatFits:CGSizeMake(width - TYAlertViewPaddingWidth * 2.0, CGFLOAT_MAX)];
            CGRect titleLabelFrame = CGRectMake(TYAlertViewPaddingWidth, self.innerMarginHeight, width - TYAlertViewPaddingWidth * 2.0, titleLabelSize.height);
            
            self.titleBtn.frame = titleLabelFrame;
            [self.titleScrollView addSubview:self.titleBtn];
            
            contentOffsetY = CGRectGetMinY(self.titleBtn.frame) + CGRectGetHeight(self.titleBtn.frame);
            contentOffsetY += self.innerMarginHeight / 2.0;
            self.titleScrollView.contentSize = CGSizeMake(width, contentOffsetY);
            contentOffsetY = 0;
        }
        
        if (self.title.length > 0 && self.message.length > 0 && self.seperateLineBetweenTitleAndMessage) {
            UILabel *lineLabel = [self getLineLabelWithOffset:contentOffsetY];
            [self.contentScrollView addSubview:lineLabel];
            contentOffsetY += CGRectGetHeight(lineLabel.frame);
        }
        
        if (self.message.length > 0) {
            self.messageLabel = [UILabel new];
            NSMutableParagraphStyle *stringStyle = [[NSMutableParagraphStyle alloc] init];
            stringStyle.lineSpacing = self.messageLineSpacing;
            NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:self.message attributes:@{NSParagraphStyleAttributeName: stringStyle}];
            self.messageLabel.attributedText = attributedString;
            self.messageLabel.textColor = self.messageTextColor;
            self.messageLabel.numberOfLines = 0;
            self.messageLabel.lineBreakMode = NSLineBreakByWordWrapping;
            self.messageLabel.backgroundColor = UIColor.clearColor;
            self.messageLabel.font = self.messageFont;
            
            if (self.messageTextAlignment != NSTextAlignmentCenter) {
                self.messageLabel.textAlignment = self.messageTextAlignment;
            } else {
                static dispatch_once_t onceToken;
                static CGFloat oneLineHeight;
                dispatch_once(&onceToken, ^{
                    oneLineHeight = [@"k" boundingRectWithSize:CGSizeZero options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName : self.messageFont} context:nil].size.height;
                });
                CGFloat messageHeight = [self.message boundingRectWithSize:CGSizeZero options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName : self.messageFont} context:nil].size.height;
                if (messageHeight / oneLineHeight > 4) {
                    self.messageLabel.textAlignment = NSTextAlignmentLeft;
                } else {
                    self.messageLabel.textAlignment = NSTextAlignmentCenter;
                }
            }
            
            if (!self.title.length) {
                contentOffsetY = self.innerMarginHeight;
            }
            
            CGSize messageLabelSize = [self.messageLabel sizeThatFits:CGSizeMake(width - TYAlertViewPaddingWidth * 2.0, CGFLOAT_MAX)];
            CGRect messageLabelFrame = CGRectMake(TYAlertViewPaddingWidth, contentOffsetY, width-TYAlertViewPaddingWidth * 2.0, messageLabelSize.height);
            
            
            self.messageLabel.frame = messageLabelFrame;
            [self.contentScrollView addSubview:self.messageLabel];
            
            contentOffsetY = CGRectGetMinY(self.messageLabel.frame) + CGRectGetHeight(self.messageLabel.frame);
            contentOffsetY += self.innerMarginHeight / 2.0;
            
        }
        
        if (self.innerView) {
            self.innerContainerView = [UIView new];
            self.innerContainerView.backgroundColor = UIColor.clearColor;
            CGSize size = [self.innerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
            self.innerView.ty_size = size;
            
            if (contentOffsetY == 0 && self.title.length == 0) {
                contentOffsetY += self.innerMarginHeight;
            }
            
            CGRect innerContainerViewFrame = CGRectMake(0.0, contentOffsetY, width, CGRectGetHeight(self.innerView.bounds));
            
            self.innerContainerView.frame = innerContainerViewFrame;
            [self.contentScrollView addSubview:self.innerContainerView];
            
            CGRect innerViewFrame = CGRectMake((width / 2.0) - (CGRectGetWidth(self.innerView.bounds) / 2.0),
                                               0,
                                               CGRectGetWidth(self.innerView.bounds),
                                               CGRectGetHeight(self.innerView.bounds));
            
            self.innerView.frame = innerViewFrame;
            [self.innerContainerView addSubview:self.innerView];
            
            contentOffsetY = CGRectGetMinY(self.innerContainerView.frame) + CGRectGetHeight(self.innerContainerView.frame);
        } else if (self.type == TYAlertViewTypeProgressView) {
            self.progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
            self.progressView.progress = self.progress;
            self.progressView.backgroundColor = UIColor.clearColor;
            self.progressView.progressTintColor = self.progressViewProgressTintColor;
            self.progressView.trackTintColor = self.progressViewTrackTintColor;
            
            if (self.progressViewProgressImage) {
                self.progressView.progressImage = self.progressViewProgressImage;
            }
            
            if (self.progressViewTrackImage) {
                self.progressView.trackImage = self.progressViewTrackImage;
            }
            
            CGRect progressViewFrame = CGRectMake(TYAlertViewPaddingWidth,
                                                  contentOffsetY + self.innerMarginHeight,
                                                  width - (TYAlertViewPaddingWidth * 2.0),
                                                  CGRectGetHeight(self.progressView.bounds));
            
            
            self.progressView.frame = progressViewFrame;
            [self.contentScrollView addSubview:self.progressView];
            
            contentOffsetY = CGRectGetMinY(self.progressView.frame) + CGRectGetHeight(self.progressView.frame);
            
            if (self.progressLabelText) {
                self.progressLabel = [UILabel new];
                self.progressLabel.text = self.progressLabelText;
                self.progressLabel.textColor = self.progressLabelTextColor;
                self.progressLabel.textAlignment = self.progressLabelTextAlignment;
                self.progressLabel.numberOfLines = self.progressLabelNumberOfLines;
                self.progressLabel.backgroundColor = UIColor.clearColor;
                self.progressLabel.font = self.progressLabelFont;
                self.progressLabel.lineBreakMode = self.progressLabelLineBreakMode;
                
                CGRect progressLabelFrame = CGRectMake(TYAlertViewPaddingWidth,
                                                       contentOffsetY + (self.innerMarginHeight / 2.0),
                                                       width - (TYAlertViewPaddingWidth * 2.0),
                                                       self.progressLabelNumberOfLines * self.progressLabelFont.lineHeight);
                
                self.progressLabel.frame = progressLabelFrame;
                [self.contentScrollView addSubview:self.progressLabel];
                
                contentOffsetY = CGRectGetMinY(self.progressLabel.frame) + CGRectGetHeight(self.progressLabel.frame);
            }
        } else if (self.type == TYAlertViewTypeTextField) {
            NSMutableArray *textFieldsArray = [NSMutableArray new];
            for (NSUInteger i = 0; i < self.numberOfTextFields; i++) {
                if (i != 0) {
                    UILabel *lineLabel = [self getLineLabelWithOffset:contentOffsetY];
                    lineLabel.frame = CGRectMake(TYAlertViewPaddingWidth, contentOffsetY, self.width - 2 * TYAlertViewPaddingWidth, CGRectGetHeight(lineLabel.frame));
                    [self.contentScrollView addSubview:lineLabel];
                    contentOffsetY += CGRectGetHeight(lineLabel.frame);
                }
                
                // -----
                TYAlertViewTextField *textField = [TYAlertViewTextField new];
                textField.tintColor = self.tintColor;
                textField.delegate = self;
                textField.tag = i;
                textField.backgroundColor = self.textFieldsBackgroundColor;
                [textField addTarget:self action:@selector(textFieldChanged:) forControlEvents:UIControlEventEditingChanged];
                
                textField.textColor = self.textFieldsTextColor;
                textField.font = self.textFieldsFont;
                textField.textAlignment = self.textFieldsTextAlignment;
                textField.clearsOnBeginEditing = self.textFieldsClearsOnBeginEditing;
                textField.adjustsFontSizeToFitWidth = self.textFieldsAdjustsFontSizeToFitWidth;
                textField.minimumFontSize = self.textFieldsMinimumFontSize;
                textField.clearButtonMode = self.textFieldsClearButtonMode;
                textField.accessibilityIdentifier = [NSString stringWithFormat:@"alert_textfied_%ld", i];
                
                if (i == self.numberOfTextFields - 1) {
                    textField.returnKeyType = UIReturnKeyDone;
                } else {
                    textField.returnKeyType = UIReturnKeyNext;
                }
                
                if (self.textFieldsSetupHandler) {
                    self.textFieldsSetupHandler(textField, i);
                }
                
                if (i == 0 && self.disableButtonIfNoText) {
                    enableFirstButton = textField.text.length != 0;
                }
                
                CGRect textFieldFrame = CGRectMake(0.0, contentOffsetY, width, self.textFieldsHeight);
                
                textField.frame = textFieldFrame;
                [self.contentScrollView addSubview:textField];
                [textFieldsArray addObject:textField];
                
                contentOffsetY = CGRectGetMinY(textField.frame) + CGRectGetHeight(textField.frame);
            }
            
            self.textFieldsArray = textFieldsArray;
            
            contentOffsetY -= (self.innerMarginHeight / 2.f - 10.f);
        }
        
        if (self.cancelAction && self.style == TYAlertViewStyleActionSheet && self.cancelButtonOffsetY != 0) {
            [self addCancelButton];
        }
        
        CGFloat buttonOffset = 0;
        NSInteger titleCount = self.actions.count;
        
        BOOL shouldAddLineAboveButton = self.style != TYAlertViewStyleActionSheet && !self.shouldHideLine;
        
        if (shouldAddLineAboveButton) {
            contentOffsetY += self.spacingBetweenContentAndButton ?: self.innerMarginHeight / 2.f;
        }
        
        if (titleCount != 0 && shouldAddLineAboveButton) {
            UILabel *lineLabel = [self getLineLabelWithOffset:buttonOffset];
            [self.buttonScrollView addSubview:lineLabel];
            buttonOffset = CGRectGetMinY(lineLabel.frame) + CGRectGetHeight(lineLabel.frame);
        }
        
        
        if (titleCount > 2 || self.style == TYAlertViewStyleActionSheet) {
            for (NSUInteger i = 0; i < self.actions.count; i++) {
                
                if (i != 0 && !self.shouldHideLine) {
                    UILabel *lineLabel = [self getLineLabelWithOffset:buttonOffset];
                    [self.buttonScrollView addSubview:lineLabel];
                    buttonOffset = CGRectGetMinY(lineLabel.frame) + CGRectGetHeight(lineLabel.frame);
                }
                TYAlertAction *action = self.actions[i];
                CGFloat actionWidth = action.width ? (action.width > self.width ? self.width : action.width ) : self.width;
                UIButton *button = [self createButtonWithAction:action];
                button.tag = i;
                if (i == self.actions.count - 1) {
                    [button setEnabled:enableFirstButton];
                }
                [self.buttonScrollView addSubview:button];
                button.frame =  CGRectMake((self.width - actionWidth) /2.f, buttonOffset, actionWidth, self.buttonHeight);
                buttonOffset += CGRectGetHeight(button.frame) + action.verticalSpacing;
                if (!self.cancelButton && self.style == TYAlertViewStyleActionSheet && i == self.actions.count - 1 ) {
                    if (@available(iOS 11.0, *)) {
                        CGFloat bottom = [UIApplication sharedApplication].keyWindow.safeAreaInsets.bottom;
                        buttonOffset += (bottom > 0 ? 20.f : 0.0);
                    }
                }
                [self.alertBtns removeAllObjects];
                [self.alertBtns addObject:button];
            }
        } else if (titleCount == 2) {
            contentOffsetY += self.spacingBetweenContentAndButton;
            CGFloat lineWidth = 1 / [UIScreen mainScreen].scale;
            UIButton *firstButton = [self createButtonWithAction:self.actions[0]];
            UIButton *scenondButton = [self createButtonWithAction:self.actions[1]];
            UILabel *lineLabel = [self getLineLabelWithOffset:0];
            
            TYAlertAction *firstAction = self.actions[0];
            TYAlertAction *secondAction = self.actions[1];
            
            CGFloat bWidth = self.width / 2.f;
            
            CGFloat firstWidth = firstAction.width ? (firstAction.width > bWidth ? bWidth : firstAction.width ) : bWidth;
            CGFloat secondWidth = secondAction.width ? (secondAction.width > bWidth ? bWidth : secondAction.width ) : bWidth;
            
            firstButton.frame = CGRectMake((self.width / 2.f - firstWidth) /2.f + firstAction.offsetX, buttonOffset, firstWidth, self.buttonHeight);
            firstButton.tag = 0;
            firstButton.enabled = firstAction.countDown == 0;
            
            scenondButton.frame = CGRectMake((self.width / 2.f * 3.f - secondWidth) /2.f + secondAction.offsetX, buttonOffset, secondWidth, self.buttonHeight);
            scenondButton.tag = 1;
            [scenondButton setEnabled:enableFirstButton && secondAction.countDown == 0];
            
            void (^updateCountDown)(TYAlertAction* acion, UIButton* btn) = ^(TYAlertAction* action, UIButton* btn){
                if (action.countDown > 0) {
                    action.countDown -= 1;
                    
                    [btn setTitle:action.countDown > 0 ? [NSString stringWithFormat:@"%@ %lds", action.title, action.countDown] : action.title forState:UIControlStateNormal];
                    btn.enabled = action.countDown == 0;
                }
            };
            
            if (firstAction.countDown > 0 || secondAction.countDown > 0) {
                self.countDownTimer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
                    
                    updateCountDown(firstAction, firstButton);
                    updateCountDown(secondAction, scenondButton);
                    if (firstButton.enabled && scenondButton.enabled) {
                        [timer invalidate];
                    }
                }];
            }
            
            lineLabel.frame = CGRectMake(self.width / 2, buttonOffset, lineWidth, self.buttonHeight);
            [self.buttonScrollView addSubview:firstButton];
            [self.buttonScrollView addSubview:scenondButton];
            [self.alertBtns removeAllObjects];
            [self.alertBtns addObject:firstButton];
            [self.alertBtns addObject:scenondButton];
            
            if (!self.shouldHideLine) {
                [self.buttonScrollView addSubview:lineLabel];
            }
            buttonOffset += CGRectGetHeight(lineLabel.frame);
            buttonOffset += MAX(firstAction.verticalSpacing, secondAction.verticalSpacing);
            
        } else if (titleCount == 1) {
            TYAlertAction *action = [self.actions objectAtIndex:0];
            CGFloat actionWidth = action.width ? (action.width > self.width ? self.width : action.width ) : self.width;
            UIButton *firstButton = [self createButtonWithAction:self.actions[0]];
            
            [firstButton setEnabled:enableFirstButton];
            firstButton.frame = CGRectMake((self.width - actionWidth) /2.f, buttonOffset, actionWidth, self.buttonHeight);
            firstButton.tag = 0;
            [self.buttonScrollView addSubview:firstButton];
            buttonOffset += CGRectGetHeight(firstButton.frame);
            buttonOffset += action.verticalSpacing;
            [self.alertBtns removeAllObjects];
            [self.alertBtns addObject:firstButton];
        }
        
        self.contentScrollView.contentSize = CGSizeMake(width, contentOffsetY);
        self.buttonScrollView.contentSize = CGSizeMake(width, buttonOffset);
        
    }
}

- (void)layoutViewsWithSize:(CGSize)size {
    if (CGSizeEqualToSize(size, CGSizeZero)) {
        size = self.viewController.view.bounds.size;
    }
    // -----
    
    CGFloat width = self.width;
    // -----
    
    self.view.frame = CGRectMake(0.0, 0.0, size.width, size.height);
    self.backgroundView.frame = CGRectMake(0.0, 0.0, size.width, size.height);
    
    // -----
    CGFloat heightMax = size.height * 4.0 / 6.0;
    if (self.keyboardHeight != 0) {
        heightMax = (size.height - self.keyboardHeight) * 4.0 / 6.0;
    }
    
    if (self.style == TYAlertViewStyleActionSheet && self.cancelButtonOffsetY != 0 && self.cancelButton) {
        heightMax -= self.buttonHeight + self.cancelButtonOffsetY;
    }
    
    CGFloat titleHeight = self.titleScrollView.contentSize.height;
    CGFloat contentHeight = self.contentScrollView.contentSize.height;
    CGFloat buttonHeight = self.buttonScrollView.contentSize.height;
    
    
    if (titleHeight + contentHeight + buttonHeight < heightMax) {
        heightMax = titleHeight + contentHeight + buttonHeight;
    } else {
        if (buttonHeight < heightMax * 0.3) {
            contentHeight = heightMax - buttonHeight - titleHeight;
        } else if (contentHeight < heightMax * 0.7) {
            buttonHeight = heightMax - contentHeight - titleHeight;
        } else {
            CGFloat height = heightMax - titleHeight;
            contentHeight = height * 0.7;
            buttonHeight = height * 0.3;
        }
    }
    
    // -----
    
    CGRect scrollViewFrame = CGRectZero;
    CGRect titleScrollViewFrame = CGRectZero;
    CGRect contentScrollViewFrame = CGRectZero;
    CGRect buttonScrollViewFrame = CGRectZero;
    
    CGAffineTransform scrollViewTransform = CGAffineTransformIdentity;
    CGFloat scrollViewAlpha = 1.0;
    
    if (self.style == TYAlertViewStyleAlert) {
        scrollViewFrame = CGRectMake((size.width - width) / 2.0, (size.height - self.keyboardHeight - heightMax) / 2.0, width, heightMax);
        titleScrollViewFrame = CGRectMake(0, 0, width, titleHeight);
        contentScrollViewFrame = CGRectMake(0, CGRectGetMinY(titleScrollViewFrame) + CGRectGetHeight(titleScrollViewFrame), width, contentHeight);
        buttonScrollViewFrame = CGRectMake(0, CGRectGetMinY(contentScrollViewFrame) + CGRectGetHeight(contentScrollViewFrame) , width, buttonHeight);
        if (!self.isShowing) {
            scrollViewTransform = CGAffineTransformMakeScale(1.2, 1.2);
            
            scrollViewAlpha = 0.0;
        }
    } else {
        CGFloat bottomShift = 8.0;
        
        if (!self.cancelButton) {
            bottomShift = 0.f;
        }
        
        if (self.style == TYAlertViewStyleActionSheet && self.cancelButtonOffsetY != 0  && self.cancelButton) {
            bottomShift += self.buttonHeight + self.cancelButtonOffsetY;
        }
        
        scrollViewFrame = CGRectMake((size.width - width) / 2.0, size.height - bottomShift - heightMax, width, heightMax);
        titleScrollViewFrame = CGRectMake(0, 0, width, titleHeight);
        contentScrollViewFrame = CGRectMake(0, CGRectGetMinY(titleScrollViewFrame) + CGRectGetHeight(titleScrollViewFrame), width, contentHeight);
        buttonScrollViewFrame = CGRectMake(0, CGRectGetMinY(contentScrollViewFrame) + CGRectGetHeight(contentScrollViewFrame), width, buttonHeight);
    }
    
    // -----
    
    if (self.style == TYAlertViewStyleActionSheet) {
        CGRect cancelButtonFrame = CGRectZero;
        
        if (self.isCancelButtonSperateWithSelf && self.cancelButton) {
            cancelButtonFrame = CGRectMake((size.width - width) / 2.0, size.height - self.cancelButtonOffsetY - self.buttonHeight, width, self.buttonHeight + self.cancelButtonOffsetY);
        }
        
        self.scrollViewCenterShowed = CGPointMake(CGRectGetMinX(scrollViewFrame) + (CGRectGetWidth(scrollViewFrame) / 2.0),
                                                  CGRectGetMinY(scrollViewFrame) + (CGRectGetHeight(scrollViewFrame) / 2.0));
        
        self.cancelButtonCenterShowed = CGPointMake(CGRectGetMinX(cancelButtonFrame) + (CGRectGetWidth(cancelButtonFrame) / 2.0),
                                                    CGRectGetMinY(cancelButtonFrame) + (CGRectGetHeight(cancelButtonFrame) / 2.0));
        
        self.cancelSepViewCenterShowed = CGPointMake(CGRectGetMinX(cancelButtonFrame) + (CGRectGetWidth(cancelButtonFrame) / 2.0),
                                                     CGRectGetMinY(cancelButtonFrame) - 4);
        // -----
        
        CGFloat commonHeight = CGRectGetHeight(scrollViewFrame) + (self.cancelButton ? 8.0 : 0.0);
        
        if (self.style == TYAlertViewStyleActionSheet && self.cancelButtonOffsetY != 0 && self.cancelButton) {
            commonHeight += self.buttonHeight + self.cancelButtonOffsetY;
        }
        
        self.scrollViewCenterHidden = CGPointMake(CGRectGetMinX(scrollViewFrame) + (CGRectGetWidth(scrollViewFrame) / 2.0),
                                                  CGRectGetMinY(scrollViewFrame) + (CGRectGetHeight(scrollViewFrame) / 2.0) + commonHeight + self.layerBorderWidth + self.layerShadowRadius);
        
        self.cancelButtonCenterHidden = CGPointMake(CGRectGetMinX(cancelButtonFrame) + (CGRectGetWidth(cancelButtonFrame) / 2.0),
                                                    CGRectGetMinY(cancelButtonFrame) + (CGRectGetHeight(cancelButtonFrame) / 2.0) + commonHeight);
        
        self.cancelSepViewCenterHidden = CGPointMake(CGRectGetMinX(cancelButtonFrame) + (CGRectGetWidth(cancelButtonFrame) / 2.0),
                                                     CGRectGetMinY(cancelButtonFrame) - 4 + commonHeight);
        
        if (!self.isShowing) {
            scrollViewFrame.origin.y += commonHeight;
            
            if (self.style == TYAlertViewStyleActionSheet && self.cancelButtonOffsetY != 0 && self.cancelButton) {
                cancelButtonFrame.origin.y += commonHeight;
            }
        }
        
        // -----
        
        if (self.style == TYAlertViewStyleActionSheet && self.cancelButton) {
            self.cancelButton.frame = cancelButtonFrame;
            
            
            CGFloat offset = self.layerBorderWidth + self.layerShadowRadius;
            self.shadowCancelView.frame = CGRectInset(cancelButtonFrame, -offset, -offset);
            [self.shadowCancelView setNeedsDisplay];
            self.cancelSeperateView.frame = CGRectMake(0, CGRectGetMinY(self.shadowCancelView.frame) - 9, self.width, 9);
            
            self.blurCancelView.frame = CGRectInset(cancelButtonFrame, -self.layerBorderWidth, -self.layerBorderWidth);
        }
    }
    
    
    
    self.contentView.frame = scrollViewFrame;
    self.contentView.transform = scrollViewTransform;
    self.contentView.alpha = scrollViewAlpha;
    
    self.contentScrollView.frame = contentScrollViewFrame;
    self.buttonScrollView.frame = buttonScrollViewFrame;
    self.titleScrollView.frame = titleScrollViewFrame;
    
    CGFloat offset = self.layerBorderWidth + self.layerShadowRadius;
    self.shadowView.frame = CGRectInset(scrollViewFrame, -offset, -offset);
    self.shadowView.transform = scrollViewTransform;
    self.shadowView.alpha = scrollViewAlpha;
    [self.shadowView setNeedsDisplay];
    
    // -----
    
    self.blurView.frame = CGRectInset(scrollViewFrame, -self.layerBorderWidth, -self.layerBorderWidth);
    self.blurView.transform = scrollViewTransform;
    self.blurView.alpha = scrollViewAlpha;
    
    if (self.style == TYAlertViewStyleActionSheet) {
        CAShapeLayer *layer = [CAShapeLayer new];
        [layer setPath:[UIBezierPath bezierPathWithRoundedRect:self.blurView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(10.f, 10.f)].CGPath];
        [self.blurView.contentView.layer setMask:layer];
    }
    
}

- (void)addCancelButton {
    self.shadowCancelView = [TYAlertShadowView new];
    self.shadowCancelView.clipsToBounds = YES;
    self.shadowCancelView.userInteractionEnabled = NO;
    self.shadowCancelView.cornerRadius = self.layerCornerRadius;
    self.shadowCancelView.strokeColor = self.layerBorderColor;
    self.shadowCancelView.strokeWidth = self.layerBorderWidth;
    self.shadowCancelView.shadowColor = self.layerShadowColor;
    self.shadowCancelView.shadowBlur = self.layerShadowRadius;
    self.shadowCancelView.shadowOffset = self.layerShadowOffset;
    [self.view insertSubview:self.shadowCancelView belowSubview:self.contentView];
    
    self.blurCancelView = [[UIVisualEffectView alloc] initWithEffect:self.backgroundBlurEffect];
    self.blurCancelView.contentView.backgroundColor = self.backgroundColor;
    self.blurCancelView.clipsToBounds = YES;
    self.blurCancelView.layer.cornerRadius = self.layerCornerRadius;
    self.blurCancelView.layer.borderWidth = self.layerBorderWidth;
    self.blurCancelView.layer.borderColor = self.layerBorderColor.CGColor;
    self.blurCancelView.userInteractionEnabled = NO;
    [self.view insertSubview:self.blurCancelView aboveSubview:self.shadowCancelView];
    
    self.cancelButton = [self createButtonWithAction:self.cancelAction];
    if (@available(iOS 11.0, *)) {
        CGFloat bottom = [UIApplication sharedApplication].keyWindow.safeAreaInsets.bottom;
        self.cancelButton.titleEdgeInsets = UIEdgeInsetsMake(0, 0, bottom, 0);
    }
    [self.cancelButton removeTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.cancelButton addTarget:self action:@selector(cancelButtonAction:) forControlEvents:UIControlEventTouchUpInside];
    
    self.cancelButton.layer.masksToBounds = YES;
    self.cancelButton.layer.cornerRadius = self.layerCornerRadius - self.layerBorderWidth - (self.layerBorderWidth ? 1.0 : 0.0);
    [self.view insertSubview:self.cancelButton aboveSubview:self.blurCancelView];
    
    self.cancelSeperateView = [[UIView alloc] initWithFrame:CGRectZero];
    self.cancelSeperateView.backgroundColor = TYTheme.theme.B1;
    [self.view insertSubview:self.cancelSeperateView aboveSubview:self.blurCancelView];
}

- (void)addBackgroundView {
    self.backgroundView.backgroundColor = self.coverColor;
    self.backgroundView.effect = self.coverBlurEffect;
}

- (void)addShadowView {
    self.shadowView = [TYAlertShadowView new];
    self.shadowView.clipsToBounds = YES;
    self.shadowView.userInteractionEnabled = NO;
    self.shadowView.cornerRadius = self.layerCornerRadius;
    self.shadowView.strokeColor = self.layerBorderColor;
    self.shadowView.strokeWidth = self.layerBorderWidth;
    self.shadowView.shadowColor = self.layerShadowColor;
    self.shadowView.shadowBlur = self.layerShadowRadius;
    self.shadowView.shadowOffset = self.layerShadowOffset;
    [self.view addSubview:self.shadowView];
}

- (void)addBlurView {
    
    self.blurView = [[UIVisualEffectView alloc] initWithEffect:self.backgroundBlurEffect];
    self.blurView.contentView.backgroundColor = self.backgroundColor;
    self.blurView.clipsToBounds = YES;
    self.blurView.layer.cornerRadius = self.layerCornerRadius;
    self.blurView.layer.borderWidth = self.layerBorderWidth;
    self.blurView.layer.borderColor = self.layerBorderColor.CGColor;
    self.blurView.userInteractionEnabled = NO;
    [self.view addSubview:self.blurView];
}

- (void)addContentView {
    self.contentView = [[UIView alloc] init];
    self.contentView.backgroundColor = UIColor.clearColor;
    self.contentView.clipsToBounds = YES;
    self.contentView.layer.cornerRadius = self.layerCornerRadius - self.layerBorderWidth - (self.layerBorderWidth ? 1.0 : 0.0);
    [self.view addSubview:self.contentView];
    
}

- (void)addContentScrollView {
    self.contentScrollView = [UIScrollView new];
    self.contentScrollView.backgroundColor = UIColor.clearColor;
    self.contentScrollView.showsVerticalScrollIndicator = NO;
    self.contentScrollView.alwaysBounceVertical = NO;
    self.contentScrollView.clipsToBounds = YES;
    [self.contentView addSubview:self.contentScrollView];
}

- (void)addTitleScrollView {
    self.titleScrollView = [UIScrollView new];
    self.titleScrollView.backgroundColor = UIColor.clearColor;
    self.titleScrollView.showsVerticalScrollIndicator = NO;
    self.titleScrollView.alwaysBounceVertical = NO;
    self.titleScrollView.clipsToBounds = YES;
    [self.contentView addSubview:self.titleScrollView];
}

- (void)addButtonScrollView {
    self.buttonScrollView = [UIScrollView new];
    self.buttonScrollView.backgroundColor = UIColor.clearColor;
    self.buttonScrollView.showsVerticalScrollIndicator = NO;
    self.buttonScrollView.alwaysBounceVertical = NO;
    self.buttonScrollView.showsHorizontalScrollIndicator = NO;
    self.buttonScrollView.clipsToBounds = YES;
    [self.contentView addSubview:self.buttonScrollView];
}

#pragma mark - action

- (CGRect)getFrameWithAction:(TYAlertAction *)action offset:(CGFloat)buttonOffset {
    if (action.width) {
        return CGRectMake((self.width - action.width) /2.f, buttonOffset, action.width, self.buttonHeight);
    } else {
        return CGRectMake(0, buttonOffset, self.width, self.buttonHeight);
    }
}

- (UIButton *)createButtonWithAction:(TYAlertAction *)action {
    return ({
        UIButton *button = [[UIButton alloc] init];
        button.titleLabel.font = action.titleFont;
        button.titleLabel.textAlignment = action.textAligment;
        button.adjustsImageWhenHighlighted = NO;
        if (action.accessibilityIdentifier) {
            button.accessibilityIdentifier = action.accessibilityIdentifier;
        } else {
            button.accessibilityIdentifier = [NSString stringWithFormat:@"alert_%ld", (long)action.index];
        }
        
        button.layer.cornerRadius = action.cornerRadius;
        button.layer.borderWidth = action.borderWidth;
        button.layer.borderColor = action.borderColor.CGColor;
        button.layer.masksToBounds = YES;
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [button setTitleColor:action.titleColor forState:UIControlStateNormal];
        [button setTitleColor:action.titleColorHighlighted forState:UIControlStateHighlighted];
        [button setTitleColor:action.titleColorDisabled ? : TYTheme.theme.B4.N4 forState:UIControlStateDisabled];
        [button setBackgroundImage:[TYAlertView image1x1WithColor:action.backgroundColor] forState:UIControlStateNormal];
        [button setBackgroundImage:[TYAlertView image1x1WithColor:action.backgroundColorHighlighted] forState:UIControlStateHighlighted];
        [button setBackgroundImage:[TYAlertView image1x1WithColor:action.backgroundColorHighlighted] forState:UIControlStateSelected];
        [button setTitle:action.title forState:UIControlStateNormal];
        if (action.countDown > 0) {
            [button setTitle:[NSString stringWithFormat:@"%@ %lds", action.title, action.countDown] forState:UIControlStateNormal];
            
        }
        if (action.textAligment == NSTextAlignmentLeft) {
            button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
        } else if (action.textAligment == NSTextAlignmentRight) {
            button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
        }
        button;
    });
}

- (UILabel *)getLineLabelWithOffset:(CGFloat)offsetY {
    return ({
        UILabel *label = [[UILabel alloc] init];
        label.backgroundColor = TYTheme.theme.B4.N7;
        label.ty_height = 1 / [UIScreen mainScreen].scale;
        label.ty_width = self.style == TYAlertViewStyleActionSheet ? self.width - 30.f : self.width;
        if (self.style == TYAlertViewStyleActionSheet) {
            label.ty_left = 15.f;
        }
        label.ty_top = offsetY;
        label;
    });
}

#pragma mark - textField delegate

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    if (textField.tag < self.textFieldsArray.count - 1) {
        UITextField *nextTextField = [self.textFieldsArray objectAtIndex:textField.tag + 1];
        [nextTextField becomeFirstResponder];
    } else if (textField.returnKeyType == UIReturnKeyDone) {
        [textField resignFirstResponder];
    }
    return YES;
}

- (void)textFieldChanged:(UITextField *)textField {
    if (textField.tag != 0 || !self.disableButtonIfNoText) {
        return;
    }
    
    NSCharacterSet *set = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    NSString *textString = [textField.text stringByTrimmingCharactersInSet:set];
    UIButton *btn = [self.buttonScrollView viewWithTag:self.actions.count - 1];
    if ([btn isMemberOfClass:[UIButton class]]) {
        if (textField.text.length && textString.length) {
            [btn setEnabled:YES];
        } else {
            [btn setEnabled:NO];
        }
    }
    
    return;
}

#pragma mark - call back

- (void)cancelAction:(UIGestureRecognizer *)gesture {
    
    if (self.screenTapHandler) {
        self.screenTapHandler(self);
    }
    
    if (!self.cancelOnTouch) {
        return;
    }
    [self dismissAnimated:YES completionHandler:nil];
}

- (void)cancelButtonAction:(UIButton *)cancelButton {
    [self.countDownTimer invalidate];
    if (self.dismissOnAction) {
        [cancelButton setSelected:YES];
        [self dismissAnimated];
    }
    
    if (self.actionHandler) {
        self.actionHandler(self, 0);
    }
    
    if (self.cancelAction && self.cancelAction.alertAction) {
        self.cancelAction.alertAction();
    }
    
}

- (void)buttonAction:(UIButton *)button {
    [self.countDownTimer invalidate];
    if (self.dismissOnAction) {
        [button setSelected:YES];
        [self dismissAnimated];
    }
    TYAlertAction *action = [self.actions objectAtIndex:button.tag];
    if (self.actionHandler) {
        self.actionHandler(self, action.index);
    }
    
    if (action && action.alertAction) {
        action.alertAction();
    }
}


- (void)addAlertActions:(NSArray<TYAlertAction *> *)actions {
    [actions enumerateObjectsUsingBlock:^(TYAlertAction * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [self addAlertAction:obj];
    }];
}

- (void)addAlertAction:(TYAlertAction * )alertAction {
    if (alertAction.isCancel) {
        self.cancelAction = alertAction;
        self.cancelButtonTitle = alertAction.title;
        alertAction.index = 0;
        
        [self.actions enumerateObjectsUsingBlock:^(TYAlertAction *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if (obj.isCancel) {
                NSAssert(NO, @"AlertView cant's has two cancel button");
            }
            obj.index += 1;
        }];
        
        if (self.style != TYAlertViewStyleActionSheet) {
            if (self.actions.count < 2) {
                [self.actions insertObject:alertAction atIndex:0];
            } else {
                [self.actions addObject:alertAction];
            }
        }
    } else {
        alertAction.index = self.actions.count;
        if (self.cancelAction && self.style == TYAlertViewStyleAlert) {
            if (self.actions.count < 2) {
                [self.actions addObject:alertAction];
            } else {
                if (self.actions.count == 2) {
                    [self.actions removeObject:self.cancelAction];
                    [self.actions addObject:self.cancelAction];
                }
                NSInteger cancelIndex = [self.actions indexOfObject:self.cancelAction];
                [self.actions insertObject:alertAction atIndex:cancelIndex];
            }
        } else {
            if (self.style == TYAlertViewStyleActionSheet) {
                alertAction.index = self.actions.count + 1;
            }
            [self.actions addObject:alertAction];
        }
    }
}

#pragma mark - setter
- (void)setCancleBtnColor:(UIColor *)cancleBtnColor {
    _cancleBtnColor = cancleBtnColor;
    UIButton *cancleBtn = self.alertBtns.count < 3 ? self.alertBtns.firstObject : self.alertBtns.lastObject;
    [cancleBtn setTitleColor:cancleBtnColor forState:UIControlStateNormal];
    [cancleBtn setTitleColor:cancleBtnColor forState:UIControlStateHighlighted];
    
}

- (void)setOtherBtnColor:(UIColor *)otherBtnColor {
    _otherBtnColor = otherBtnColor;
    NSInteger cancelIndex = self.actions.count < 3 ? 0 : self.actions.count - 1;
    if(self.alertBtns.count > 0){
        [self.alertBtns enumerateObjectsUsingBlock:^(UIButton *obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if (idx != cancelIndex) {
                [obj setTitleColor:otherBtnColor forState:UIControlStateNormal];
                [obj setTitleColor:otherBtnColor forState:UIControlStateHighlighted];
            }
        }];
    }
    if(self.actions.count > 0){
        [self.actions enumerateObjectsUsingBlock:^(TYAlertAction *obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if (idx != cancelIndex) {
                [obj setTitleColor:otherBtnColor];
            }
        }];
    }
    
}

- (void)setCancleFont:(UIFont *)cancleFont {
    _cancleFont = cancleFont;
    UIButton *cancleBtn = self.alertBtns.firstObject;
    cancleBtn.titleLabel.font = cancleFont;
    if (self.cancelAction) {
        self.cancelAction.titleFont = cancleFont;
    }
    else{
        
        TYAlertAction* action = self.actions.count < 3 ? self.actions.firstObject : self.actions.lastObject;
        action.titleFont = cancleFont;
    }
}

- (void)setOtherFont:(UIFont *)otherFont {
    _otherFont = otherFont;
    NSInteger cancelIndex = self.actions.count < 3 ? 0 : self.actions.count - 1;
    [self.actions enumerateObjectsUsingBlock:^(TYAlertAction *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (idx != cancelIndex) {
            obj.titleFont = otherFont;
        }
    }];
}

#pragma mark - private method
#pragma mark - getters
- (NSMutableArray *)alertBtns {
    if (!_alertBtns) {
        _alertBtns = [NSMutableArray array];
    }
    return _alertBtns;
}

- (CGFloat)innerMarginHeight {
    if (_innerMarginHeight == 0) {
        return TY_ScreenAdaptionLength(self.style == TYAlertViewStyleAlert ? 24.0 : 20.0);
    }
    return _innerMarginHeight;
}

- (BOOL)isCancelButtonSperateWithSelf {
    return self.style == TYAlertViewStyleActionSheet && self.cancelButtonOffsetY != 0;
}

- (CGFloat)width {
    CGSize size = [TYAlertView appWindow].bounds.size;
    if (self.showInView) {
        size = self.showInView.bounds.size;
    }
    
    if (_width != 0) {
        CGFloat result = MIN(size.width, size.height);
        
        if (_width < result) {
            result = _width;
        }
        
        return result;
    }
    
    if (self.style == TYAlertViewStyleAlert) {
        return TY_ScreenAdaptionLength(315);
    }
    
    return MIN(size.width, size.height);
}

+ (CGFloat)suggestWidthWithStyle:(TYAlertViewStyle)style {
    CGSize size = [self appWindow].bounds.size;
    
    if (style == TYAlertViewStyleAlert) {
        return TY_ScreenAdaptionLength(315.f);
    }
    
    return MIN(size.width, size.height);
}

+ (UIWindow *)appWindow {
    return [UIApplication sharedApplication].windows[0];
}

+ (UIImage *)image1x1WithColor:(UIColor *)color {
    if (!color) return nil;
    
    CGRect rect = CGRectMake(0.0, 0.0, 1.0, 1.0);
    
    UIGraphicsBeginImageContext(rect.size);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, rect);
    
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return image;
}


#pragma mark - deprecated

+ (void)simpleAlertWithTitle:(NSString *)title
                     message:(NSString *)message
                 cancelTitle:(NSString *)cancelTitle {
    [self alertWithTitle:title message:message customView:nil cancelTitle:cancelTitle cancelColor:nil otherTitles:nil clickAction:nil];
}

+(void)alertWithTitle:(NSString *)title
              message:(NSString *)message
          cancelTitle:(NSString *)cancelTitle
          otherTitles:(NSArray *)titles
          clickAction:(void (^)(TYAlertView *, NSInteger))clickAction {
    [self alertWithTitle:title message:message customView:nil cancelTitle:cancelTitle cancelColor:nil otherTitles:titles clickAction:clickAction];
}

+ (void)alertWithTitle:(NSString *)title
               message:(NSString *)message
            customView:(UIView *)customView
           cancelTitle:(NSString *)cancelTitle
           cancelColor:(UIColor *)cancelColor
           otherTitles:(NSArray *)titles
           clickAction:(void (^)(TYAlertView *, NSInteger))clickAction {
    
    [self alertInView:nil title:title message:message customView:customView cancelTitle:cancelTitle cancelColor:cancelColor otherTitles:titles clickAction:clickAction];
}

+ (void)alertWithTitle:(NSString *)title
               message:(NSString *)message
             alignment:(NSTextAlignment)alignment
           cancelTitle:(NSString *)cancelTitle
           otherTitles:(NSArray *)titles
           clickAction:(void(^)(TYAlertView *view,NSInteger buttonIndex))clickAction {
    [self alertInView:nil title:title message:message alignment:alignment customView:nil cancelTitle:cancelTitle cancelColor:nil otherTitles:titles clickAction:clickAction];
}

+ (void)alertInView:(UIView *)view
              title:(NSString *)title
            message:(NSString *)message
         customView:(UIView *)customView
        cancelTitle:(NSString *)cancelTitle
        cancelColor:(UIColor *)cancelColor
        otherTitles:(NSArray *)titles
        clickAction:(void (^)(TYAlertView *, NSInteger))clickAction {
    
    [self alertInView:view
                title:title
              message:message
            alignment:NSTextAlignmentCenter
           customView:customView
          cancelTitle:cancelTitle
          cancelColor:cancelColor
          otherTitles:titles
          clickAction:clickAction];
}

+ (void)alertInView:(UIView *)view
              title:(NSString *)title
            message:(NSString *)message
          alignment:(NSTextAlignment)alignment
         customView:(UIView *)customView
        cancelTitle:(NSString *)cancelTitle
        cancelColor:(UIColor *)cancelColor
        otherTitles:(NSArray *)titles
        clickAction:(void (^)(TYAlertView *, NSInteger buttonIndex))clickAction {
    TYAlertView *alertView =  [[TYAlertView alloc] initWithViewAndTitle:title message:message view:customView style:TYAlertViewStyleAlert buttonTitles:titles cancelButtonTitle:cancelTitle actionHandler:clickAction];
    alertView.messageTextAlignment = alignment;
    if (view) {
        [alertView showInView:view];
    } else {
        [alertView showAnimated];
    }
}

- (void)setTitleTextColor:(UIColor *)titleTextColor
{
    _titleTextColor = titleTextColor;
    if (self.titleBtn) {
        [self.titleBtn setTitleColor:titleTextColor forState:UIControlStateNormal];
    }
}

-(void)setTitleImage:(UIImage *)titleImage{
    _titleImage = titleImage;
    [self.titleBtn setImage:titleImage forState:UIControlStateNormal];
}
@end



